﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Web;
using System.Net;
using System.Text;
using System.IO;
using System.Xml;
using HtmlAgilityPack;
using FinanceGoldPointDal.DTO;
using System.Diagnostics;
using FinanceGoldPointDal.DAL;
using System.Globalization;

namespace FinanceGoldPointDal.Utils
{
  public class SymbolsGetter : BaseStockUtil
    {
    QuoteUtilsYHOO _yhooQuoteUtils = new QuoteUtilsYHOO();

      //http://download.finance.yahoo.com/d/quotes.csv?s=%40%5EDJI,GOOG&f=nsl1op&e=.csv




    public List<BaseQuoteData> GetQuotes(string[] tickers, int pLevel_0_1_2_3)
        {
          // symbol-last trade-last trade time -Open-High-Low-Change (real time)
          string quoteUrlIndicators = _yhooQuoteUtils.GetYHOOQuerySymbol(pLevel_0_1_2_3);

          List<BaseQuoteData> quotes = new List<BaseQuoteData>();
          string fullQuoteUrl = QuoteUtilsYHOO.QuoteUrlMainYHOO;
          string symbolsString = String.Empty;
          foreach (string q in tickers)
          {
            fullQuoteUrl += q + "+";
          }

          fullQuoteUrl = fullQuoteUrl.TrimEnd(new char[] { '+' });
          fullQuoteUrl += quoteUrlIndicators;

          var result = DownloadWebString(fullQuoteUrl);

          if (result.HasErrors)
          {
            return null;
          }
          var quoteLines = splitQuoteInArray(result.Dati);
      
          if (quoteLines== null) return quotes;

          BaseQuoteData quote = null;
          string changesegnal = "";
          foreach (string ql in quoteLines)
          {
            if (ql != String.Empty)
            {
              string[] raw = ql.Split(',');

              if (string.IsNullOrEmpty(raw[8].Trim()))
                raw[8] = raw[7].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)[1];

              changesegnal = raw[8].Substring(0,1);

              if (raw[8].Contains("%"))
                raw[8] = raw[8].Substring(0,raw[8].Length-1);

              quote = new BaseQuoteData(raw[0], getDoubleNullValFromGB(raw[1]), raw[2],
                getDoubleNullValFromGB(raw[3]), getDoubleNullValFromGB(raw[4]), getDoubleNullValFromGB(raw[5]), raw[6], raw[7],
                changesegnal, getDoubleNullValFromGB(raw[8]),
                 raw[9], raw[10], raw[11],raw[12],raw[13],raw[14],raw[15],
                 raw[16], raw[17], raw[18], raw[19], raw[20], raw[21], raw[22], 
                 raw[23], raw[24], raw[25] 
                 );
             


              quotes.Add(quote);
            }
          }
          return quotes;
        }

   


        public RetData<IList<YHOOFullQuote>> GetFullQuotes(string[] tickers)
        {
          // symbol-last trade-last trade time -Open-High-Low-Change (real time)
          string quoteUrlIndicators = _yhooQuoteUtils.GetStringFullYHOOQuery();

          var quotes = new List<YHOOFullQuote>();
          string fullQuoteUrl = QuoteUtilsYHOO.QuoteUrlMainYHOO;
          string symbolsString = String.Empty;
          foreach (string q in tickers)
          {
            fullQuoteUrl += q + "+";
          }

          fullQuoteUrl = fullQuoteUrl.TrimEnd(new char[] { '+' });
          fullQuoteUrl += quoteUrlIndicators;

          var result = DownloadWebString(fullQuoteUrl);
          if (result.HasErrors)
          {
            return new RetData<IList<YHOOFullQuote>>(new Exception("Dati non prelevati"));
          }

          var quoteLines  = splitQuoteInArray(result.Dati);
          if (quoteLines == null)
            return new RetData<IList<YHOOFullQuote>>(new Exception("Dati non prelevati"));

          YHOOFullQuote quote = null;
          foreach (string ql in quoteLines)
          {
            if (ql != String.Empty)
            {
              string[] rawQuote = ql.Split(',');
              quote = _yhooQuoteUtils.GetFullYHOOQuoteClass<YHOOFullQuote>(rawQuote); //Preleva i dati

              quotes.Add(quote);
            }
          }
          return new RetData<IList<YHOOFullQuote>>(quotes);
        }//fM


       


        //%2a.MI
          public static string QuoteRepositoryUrl =
          "http://it.finance.yahoo.com/lookup/all;_ylt=AlO21qwlG4xv1IdRcOsnZcLH361G;_ylu=X3oDMTFlbDY2MHU2BHBvcwMzNARzZWMDeWZpU3ltYm9sTG9va3VwUmVzdWx0cwRzbGsDaW5kaWV0cm8-?s={0}&t=A&m=ALL&r=&b=0";

          public static string AzioniItaliaUrl =
              "http://it.finance.yahoo.com/lookup/stocks;_ylt=AlO21qwlG4xv1IdRcOsnZcLI361G;_ylu=X3oDMTFlbDY2MHU2BHBvcwMzNARzZWMDeWZpU3ltYm9sTG9va3VwUmVzdWx0cwRzbGsDaW5kaWV0cm8-?s=%2a.MI&t=S&m=ALL&r=&b=0";

          static bool _procedi = false;


          public void UpdateSymbolsInDb(string pFindPattern)
          {

            try
            {

              string url =
                string.Format(AzioniItaliaUrl, pFindPattern);

              //url = HttpContext.Current.Server.UrlEncode(url);

              var result = DownloadSymbols(url);




            }
            catch (Exception ex)
            {

              throw;
            }

          }
       

          public List<SymbolDTO> DownloadSymbols(string pUrl)
          {
            Met metDal = new Met();
            List<string> quotes = new List<string>();
            string fullQuoteUrl = "";
            string symbolsString = String.Empty;
            string file = "";
            SymbolDTO temp1 = null;
            DistinctCode comparer = new DistinctCode();
            int ciclo=0, conta=0;
            List<SymbolDTO> simboli = new List<SymbolDTO>(100);
            IEnumerable<SymbolDTO> temp = null;
            SymbolDTO[] arrSimboli = null;

            Dictionary<string, SymbolDTO> dict = new Dictionary<string, SymbolDTO>(100);

            using (var wc = new WebClient())
            {

              do
              {


                fullQuoteUrl = pUrl + ciclo.ToString();
                ciclo += 20;

                file = wc.DownloadString(new Uri(fullQuoteUrl));

                  var arrSimboli2 = getXmlDox(file);

                  foreach (var item in arrSimboli2)
                  {
                    Debug.WriteLine(item.Code + "   " + conta.ToString());
                    metDal.UpdateSymbolInDB(item);
                  }

                  //  if (dict.ContainsKey(item.Code))
                  //  {
                  //    temp1 = dict[item.Code];
                  //  }
                  //  else
                  //  {
                  //    dict.Add(item.Code, item );
                  //    ++conta;
                  //  }
                  //}

                  //temp = simboli.Distinct(comparer);

                  //if (dict.Count > 300)
                  //{
                    //metDal.UpdateSymbolsDAtaFromDB(arrSimboli2);
                    //dict.Clear();
                  //}
                  
                

                

              } while (!string.IsNullOrEmpty(file));//fM

            

            return simboli ;
          }
          }

          private SymbolDTO[] getXmlDox(string file)
          {
            SymbolDTO simbolo = null;
            List<SymbolDTO> simboli = new List<SymbolDTO>(200); 
            IEnumerable<HtmlNode> nodi = null;
            HtmlNode nodo = null;
            HtmlAttribute attr = null;
            string temp = "", link = "";
            double price =0;

            HtmlDocument docB = new HtmlDocument();
            docB.LoadHtml(file);

            foreach (HtmlNode item in docB.DocumentNode.SelectNodes("//table"))
	          {
              if (item.Attributes.Contains("summary"))
              {

                foreach (var item2 in item.Descendants("tr"))
                {
                  nodi = item2.Descendants("td");

                  nodo  = nodi.Where(xx => xx.InnerHtml.Contains("href")).FirstOrDefault();
                  if (nodo != null)
                  {
                    if(nodo.OuterHtml.Contains("href"))
                      attr = nodo.ChildNodes.FindFirst("a").Attributes.Where(xx=> xx.Name.ToLower() == "href").FirstOrDefault();
                       if(attr != null)
                         link = attr.Value;
                  }
                    
                 
                  if(nodi == null  || nodi.Count() < 1) continue ;

                  simbolo = new SymbolDTO();

                  double.TryParse(nodi.ElementAt(3).InnerText,out price);
                                    
                  simbolo.Code =  nodi.ElementAt(0).InnerText;
                  simbolo.Name = nodi.ElementAt(1).InnerText;
                  simbolo.Isin = nodi.ElementAt(2).InnerText;
                  simbolo.LastChangePrice =   price;
                  simbolo.Types = nodi.ElementAt(4).InnerText;
                  simbolo.Location = nodi.ElementAt(5).InnerText;
                  simbolo.YHOOLink = link;

                  simboli.Add(simbolo);

                }


              }
	          }
            
      
            return simboli.ToArray();

          }



          public class DistinctCode : IEqualityComparer<SymbolDTO>
          {

            public bool Equals(SymbolDTO x, SymbolDTO y)
            {
              return x.Code == y.Code;
            }

            public int GetHashCode(SymbolDTO obj)
            {
              return obj.Code.GetHashCode();
            }
          }

          public string SanitizeXmlString(string xml)
          {
            if (xml == null)
            {
              throw new ArgumentNullException("xml");
            }

            StringBuilder buffer = new StringBuilder(xml.Length);

            foreach (char c in xml)
            {
              if (IsLegalXmlChar(c))
              {
                buffer.Append(c);
              }
            }

            return buffer.ToString();
          }

          /// <summary>
          /// Whether a given character is allowed by XML 1.0.
          /// </summary>
          public bool IsLegalXmlChar(int character)
          {
            return
            (
               character == 0x9 /* == '\t' == 9   */          ||
               character == 0xA /* == '\n' == 10  */          ||
               character == 0xD /* == '\r' == 13  */          ||
              (character >= 0x20 && character <= 0xD7FF) ||
              (character >= 0xE000 && character <= 0xFFFD) ||
              (character >= 0x10000 && character <= 0x10FFFF)
            );
          }

        



    }
}